package com.devops.admin.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.devops.admin.mapper.DOSHelmChartRepositoryMapper;
import com.devops.admin.model.DOSHelmChartRepository;
import com.devops.admin.model.Pagination;
import com.devops.admin.model.TableResult;
import com.devops.admin.service.DOSClusterInfoService;
import com.devops.admin.service.DOSHelmChartRepositoryService;
import com.devops.admin.util.HuHttpUtil;
import com.devops.admin.util.ThreadPoolSingleton;
import com.devops.admin.vo.DOSPageVo;
import com.devops.constant.DevOpsConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * @ClassNem DOSHelmChartRepositoryServiceImpl
 * @Description TODO
 * @Author heyabo
 * @Date 2022/3/21 08:53
 * @Version 1.0
 **/
@Service
@Slf4j
public class DOSHelmChartRepositoryServiceImpl extends ServiceImpl<DOSHelmChartRepositoryMapper, DOSHelmChartRepository> implements DOSHelmChartRepositoryService {
    @Autowired
    private DOSClusterInfoService dosClusterInfoService;

    @Override
    public TableResult<DOSHelmChartRepository> getByEnvId(DOSHelmChartRepository repository, DOSPageVo pageVo) {
        Assert.isTrue(ObjectUtil.isNotNull(repository.getEnvId()),"环境id不能为空");

        Page<DOSHelmChartRepository> page = new Page<>(pageVo.getPageNum(),pageVo.getPageSize());
        TableResult<DOSHelmChartRepository> tableResult = new TableResult<>();
        // 设置分页查询条件
        LambdaQueryWrapper<DOSHelmChartRepository> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DOSHelmChartRepository::getEnvId,repository.getEnvId())
                .orderByDesc(DOSHelmChartRepository::getCreateTime);
        Page<DOSHelmChartRepository> chartRepositoryPage = baseMapper.selectPage(page, queryWrapper);
        // 设置分页结果
        Pagination p = Pagination.builder().pageNum(chartRepositoryPage.getCurrent()).pageSize(chartRepositoryPage.getSize()).total(chartRepositoryPage.getTotal()).build();
        tableResult.setList(chartRepositoryPage.getRecords());
        tableResult.setPagination(p);
        return tableResult;
    }

    @Override
    public TableResult<DOSHelmChartRepository> getRepositorys(DOSHelmChartRepository repository,DOSPageVo pageVo) {
        Page<DOSHelmChartRepository> page = new Page<>(pageVo.getPageNum(),pageVo.getPageSize());
        TableResult<DOSHelmChartRepository> tableResult = new TableResult<>();
        LambdaQueryWrapper<DOSHelmChartRepository> queryWrapper = new LambdaQueryWrapper<>();
        //仓库名称
        if (ObjectUtil.isNotNull(repository.getRepositoryName())){
            queryWrapper.like(DOSHelmChartRepository::getRepositoryName,repository.getRepositoryName());
        }
        //仓库路径
        if (ObjectUtil.isNotNull(repository.getRepositoryUrl())){
            queryWrapper.like(DOSHelmChartRepository::getRepositoryUrl,repository.getRepositoryUrl());
        }
        //仓库状态
        if (repository.getRepositoryStatus()!=null && repository.getRepositoryStatus() > 0){
            queryWrapper.eq(DOSHelmChartRepository::getRepositoryStatus,repository.getRepositoryUrl());
        }
        queryWrapper.orderByDesc(DOSHelmChartRepository::getCreateTime);
        Page<DOSHelmChartRepository> chartRepositoryPage = baseMapper.selectPage(page, queryWrapper);
        // 设置分页结果
        Pagination p = Pagination.builder().pageNum(chartRepositoryPage.getCurrent()).pageSize(chartRepositoryPage.getSize()).total(chartRepositoryPage.getTotal()).build();
        tableResult.setList(chartRepositoryPage.getRecords());
        tableResult.setPagination(p);
        return tableResult;
    }

    @Override
    public void saveRepository(DOSHelmChartRepository repository) {
        checkRepository(repository);
        this.save(repository);
        checkRepositoryStatus(repository);
    }

    @Override
    public Boolean updateRepository(DOSHelmChartRepository repository) {
        repository.setRepositoryStatus(3);
        checkRepository(repository);
        checkRepositoryStatus(repository);
        return this.updateById(repository);
    }

    /**
     * @Author heyabo
     * @Description 校验仓库的唯一性
     * @Date 14:30 2022/4/1
     * @Param [repository]
     * @return void
     **/
    private void checkRepository(DOSHelmChartRepository repository) {
        //校验中
        repository.setRepositoryStatus(DevOpsConstant.CheckType.CHECKING);
        LambdaQueryWrapper<DOSHelmChartRepository> queryWrapper = new LambdaQueryWrapper<>();
        long count = 0L;
        if (null!=repository.getId()) {
            List<DOSHelmChartRepository> dosHelmChartRepositories = baseMapper.selectList(queryWrapper);
            for (DOSHelmChartRepository dosHelmChartRepository : dosHelmChartRepositories) {
                if (dosHelmChartRepository.getId().intValue() != repository.getId().intValue()
                    && dosHelmChartRepository.getRepositoryName().equals(repository.getRepositoryName())
                    && dosHelmChartRepository.getRepositoryUrl().equals(repository.getRepositoryUrl())){
                    count = 1L;
                    break;
                }
            }
        }else {
            queryWrapper.eq(DOSHelmChartRepository::getRepositoryName, repository.getRepositoryName())
                    .eq(DOSHelmChartRepository::getRepositoryUrl,repository.getRepositoryUrl());
            count = this.count(queryWrapper);
        }
        Assert.isTrue(count==0,"仓库重复");
    }

    /**
     * @Author heyabo
     * @Description 到集群中验证repo是否存在
     * @Date 10:36 2022/4/2
     * @Param [repositoryName]
     * @return int
     **/
    private JSONArray getRepositoryData() {
        StringBuilder domainUrl = new StringBuilder(dosClusterInfoService.getOneAvailableHelmWrapperAPIUrl());
        String url = domainUrl.append(DevOpsConstant.HelmWrapperAPIUrl.HELM_REPO_LIST_GET).toString().trim();
        JSONObject json = HuHttpUtil.dealHttpAndResponse(Method.GET,url.trim(),null,null);
        log.info("获取仓库列表结果:{}",json);
        if (json.getInt("code") == 0 && null!=json.getStr("data")) {
            return json.getJSONArray("data");
        }
        return null;
    }

    /**
     * @Author heyabo
     * @Description 校验仓库
     * @Date 11:07 2022/4/2
     * @Param [repository]
     * @return void
     **/
    private void checkRepositoryStatus(DOSHelmChartRepository repository) {
        ThreadPoolSingleton.getInstance().executeTask(()->{
            //校验失败
            int status = DevOpsConstant.CheckType.CHECK_FAILURE;
            try {
                log.info("开始异步校验repo...");
                JSONArray array = getRepositoryData();
                status = array.stream().anyMatch(obj-> {
                    JSONObject json = JSONUtil.parseObj(obj.toString());
                    return json.getStr("name").equals(repository.getRepositoryName()) && json.getStr("url").equals(repository.getRepositoryUrl());
                }) ? DevOpsConstant.CheckType.CHECK_SUCCESS : DevOpsConstant.CheckType.CHECK_FAILURE;
                repository.setRepositoryStatus(status);
                this.updateById(repository);
                log.info("repo校验结束");
            }catch (Exception e){
                log.error("校验失败", e);
                repository.setRepositoryStatus(status);
                this.updateById(repository);
            }
        });
    }
}
